/* Copyright (c) 2010 Sygic a.s., Jozef Izso.
 * Published under the MIT License.
 */

 JSDOC.PluginManager.registerPlugin(
    "OpenLayers.ClassPlugin",
    {
        ext: new Hash(),

        onBeforeParsing: function (file) {
            LOG.inform(file.name);
            var regex = /([\w+.?]+)\s+=\s+(OpenLayers\.Class)\((?:([\s\w.]+)(,)?)?\s*\{/g;
            var matches = file.src.match(regex);
            if (matches && RegExp.$3 != "") {
                LOG.warn("Class "+ RegExp.$1 + " extends "+ RegExp.$3);
                this.ext.set(RegExp.$1 +"", RegExp.$3 +"");
            }
            file.src = file.src.replace(regex, "$1 = $2($3$4 /** @lends $1# */ {");
        },

        onSymbol: function (symbol) {
            var arrayName = /([\w.]*)Lang\[(["']?)([\w\-]+)\2\]/;
            var match = symbol.name.match(arrayName);
            if (match != null) {
                var newName = match[1] + "Lang." + match[3].replace("-", "_");
                LOG.warn("Symbol "+ symbol.name +" will be changed to "+ newName +".");

                symbol.name = newName;
                symbol.alias = newName;
            }
        },

        onDocCommentSrc: function (comment) {
            var src = comment.src;
            
            // fix OpenLayers base class
            src = src.replace(/Constructor: OpenLayers\.Class/g, "@class");
            
            src = src.replace("Constructor:", "@constructs");
            var x = /@constructs (.+)/;
            var matches = src.match(x);
            if (matches && (this.ext.hasKey(RegExp.$1))) {
                var baseClass = this.ext.get(RegExp.$1);
                LOG.warn("Class "+ RegExp.$1 +" will be extended with "+ baseClass);
                src += "\n@extends "+ baseClass;
            }

            // fix Namespace documentation
            src = src.replace(/Namespace:\s*(.*)/, "@namespace $1");

            src = src.replace("Returns:", "@returns");
            src = src.replace(/Parameters(:)?/, "");
            
            // fix parameters (xmldom - {XMLNode} xml dom to serialize)
            var params = /(\w+)\s+\-\s+(\{[^}]*\})(.*)$/mg;
            while (params.test(src)) {
                src = src.replace(params, "@param $2 $1$3");
            }

            // fix {TypeA} or {TypeB} declaration
            src = src.replace(/\{(.*)\}\s+or\s+\{([^}]*)\}/g, "{$1 | $2}");

            // fix APIProperty
            src = src.replace(/((?:API)?Property|Parameter): (\w+)\s+(\{[^}]*\})\s*([\w\W]*)/g, "$4\n@type $3\n$1: $2");
            src = src.replace(/(?:APIProperty|Parameter): \w+/g, "@public");
            src = src.replace(/Property: \w+/g, "@private");
            src = src.replace(/API(?:Method|Function): \w+/g, "@public\n@desc");
            src = src.replace(/Method: \w+/g, "@private\n@desc");

            // fix Constants
            src = src.replace(/Constant: ([\w\.]+)\s+(\{[^}]*\})\s*([\w\W]*)/g, "$3\n@constant\n@type $2");

            comment.src = src;
        },

        onDocTag: function (tag) {
            // fix type in the @returns tag
            if (/return(s)?/.test(tag.title) || /param/.test(tag.title)) {
                tag.type = tag.type.replace("<", "").replace(">", "");
            }
        }
    }
);